package controllers;

import com.avaje.ebean.CallableSql;
import com.avaje.ebean.Ebean;
import models.data.Athugasemdir;
import models.data.Vidhengitafla;
import models.data.Vidhengitaflanemendur;
import models.domain.Baekur;
import models.domain.Comments;
import models.domain.Project;
import models.domain.Students;
import play.data.Form;
import play.mvc.Controller;
import play.mvc.Result;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Created with IntelliJ IDEA.
 * User: kristborga
 * Date: 28.2.2013
 * Time: 17:51
 * To change this template use File | Settings | File Templates.
 */
public class CommonController extends Controller {

    final static Form<Comments> athugasemdForm = form(Comments.class);
    //adds a comment that a student commented to a particular assignment
    public  static Result studentAddsComment(int verkefniId) {
        Form<Comments> filledForm = athugasemdForm.bindFromRequest();

        if (filledForm.hasErrors()) {
            return redirect(routes.StudentController.studentOneProject(verkefniId));
        }
        else {
            String userId = session().get("notandiId");
            Athugasemdir.create(filledForm.get().texti,userId,verkefniId,filledForm.get().hopur_id);
            //check if user is a student or a teacher
            return redirect(routes.StudentController.studentOneProject(verkefniId));
        }

    }

    //adds a comment that a teacher commented to a particular assignment
    public  static Result teacherAddsComment(int verkefniId, int hopur_id) {
        Form<Comments> filledForm = athugasemdForm.bindFromRequest();

        if (filledForm.hasErrors()) {
            return redirect(routes.TeacherController.teacherOneAssignment(verkefniId, hopur_id));
        }
        else {
            String userId = session().get("notandiId");
            Athugasemdir.create(filledForm.get().texti,userId,verkefniId,hopur_id);
            //check if user is a student or a teacher

            return redirect(routes.TeacherController.teacherOneAssignment(verkefniId, hopur_id));
        }

    }
    //Sorts a list of projects by date
    public static List<Project> sortProjectsByDate(List<Project> projects){
        Collections.sort(projects, new Comparator<Project>() {
            @Override
            public int compare(Project o1, Project o2) {
                if (o1.getHandinDateFormat() == null || o2.getHandinDateFormat() == null)
                    return 0;
                return (o2.getHandinDateFormat().compareTo(o1.getHandinDateFormat()) * (-1));
            }
        });
        return projects;
    }
    //Allows student and teacher to download a file that the teacher has submitted
    public static Result download(int spurning_id) throws Exception{
        Vidhengitafla vidhengi = Vidhengitafla.getVidhengiAll(spurning_id);//Get the attachment
        byte[] vidhengiTilAdSkila = vidhengi.getVidhengiVariable();
        response().setContentType(vidhengi.getContenttype()); //set the correct contenttype
        response().setHeader("Content-Disposition", "attachment; filename=" + vidhengi.getNafn()); //name the file with the filename, attachment means that we download the file

        return  ok(vidhengiTilAdSkila);//return the file and it starts downloading
    }
    //Allows students and teachers to open a pdf file that the teacher submitted in the browser
    public static Result openPdfInBrowser(int spurning_id) throws Exception{
        Vidhengitafla vidhengi = Vidhengitafla.getVidhengiAll(spurning_id);
        byte[] vidhengiTilAdSkila = vidhengi.getVidhengiVariable();
        response().setContentType(vidhengi.getContenttype());
        response().setHeader("Content-Disposition",  "inline; filename="+vidhengi.getNafn()); //"inline" means that we open it in browser
        return  ok(vidhengiTilAdSkila);

    }
    //Allows teachers to open a pdf file that the student submitted in the browser.
    public static Result openPdfInBrowserStudent(int verkefnaskil_id, String name){
        Vidhengitaflanemendur vidhengi = Vidhengitaflanemendur.getVidhengiAllByName(verkefnaskil_id,name);
        byte[] vidhengiTilAdSkila = vidhengi.getVidhengiVariable();
        response().setContentType(vidhengi.getContenttype());
        response().setHeader("Content-Disposition",  "inline; filename="+vidhengi.getNafn());
        return  ok(vidhengiTilAdSkila);

    }
    //Allows student and teacher to download a file that the student has submitted
    public static Result downloadStudents(int verkefnaskil_id, String name){
        Vidhengitaflanemendur vidhengi = Vidhengitaflanemendur.getVidhengiAllByName(verkefnaskil_id, name);
        byte[] vidhengiTilAdSkila = vidhengi.getVidhengiVariable();
        response().setContentType(vidhengi.getContenttype());
        response().setHeader("Content-Disposition", "attachment; filename=" + vidhengi.getNafn());
        return  ok(vidhengiTilAdSkila);
    }
    //Allows the teacher to download a zip file with all files that a group submitted for a particular assignment
    public static Result downloadZip(int verkefnihops_id, String name)throws Exception{
        List<Vidhengitaflanemendur> vidhengi = Vidhengitaflanemendur.getVidhengiListByVerkefniHops(verkefnihops_id); //get all the attachments

        byte[] zipBytes = zipBytes(vidhengi); //Call zipBytes that returns a byte[] of all assignments
        response().setContentType("application/zip");
        response().setHeader("Content-Disposition", "attachment; filename="+ name+".zip");
        return ok(zipBytes);

    }
    public static byte[] zipBytes(List<Vidhengitaflanemendur> vidhengi) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ZipOutputStream zos = new ZipOutputStream(baos);
        for(Vidhengitaflanemendur v : vidhengi){  //Go through all the attachments
            ZipEntry entry = new ZipEntry(v.getNafn());    //Add an attachment to the zipoutputstream
            entry.setSize(v.getVidhengiVariable().length);
            zos.putNextEntry(entry);
            zos.write(v.getVidhengiVariable());
            zos.closeEntry();
        }
        zos.close();  //Close the zipoutputstream
        return baos.toByteArray(); //return the byteArrayOutputStream as a byte array
    }
    //Allows a student to delete an attachment that they have submitted.
    public static Result deleteVidhengiNemendur(int vidhengi_id,int verkefni_id){
        //Play doesn't allow us to delete the attachment like we usually delete things so we created a stored procedure called remove_vidhengi_nem
        //and call it using ebean
        String sql = "{call remove_vidhengi_nem(?)}";

        CallableSql cs = Ebean.createCallableSql(sql);
        cs.setParameter(1, vidhengi_id);

        Ebean.execute(cs);
        return redirect(routes.StudentController.studentOneProject(verkefni_id));

    }
    //Sorts a list of students alphabetically.
    public static List<Students> sortStudentsByName(List<Students> studentList){
        Collections.sort(studentList, new Comparator<Students>() {
            @Override
            public int compare(Students o1, Students o2) {
                return o1.getName().compareTo(o2.getName());
            }
        });
        return studentList;
    }
    //Sort a list of books alphabetically.
    public static List<Baekur> sortBooksByName(List<Baekur> books){
        Collections.sort(books, new Comparator<Baekur>() {
            @Override
            public int compare(Baekur o1, Baekur o2) {
                return o1.getHeiti().compareTo(o2.getHeiti());
            }
        });
        return books;
    }

    public static Result studentDeletesAthugasemd(int athugasemdId, int verkefniId){
        Athugasemdir.deleteAthugaasemd(athugasemdId);
        return redirect(routes.StudentController.studentOneProject(verkefniId));

    }

    public static Result teacherDeletesAthugasemd(int athugasemdId, int verkefniId, int hopurId){
        Athugasemdir.deleteAthugaasemd(athugasemdId);
        return redirect(routes.TeacherController.teacherOneAssignment(verkefniId, hopurId));

    }
}
